package wx

import (
	"encoding/json"
	"github.com/dgrijalva/jwt-go"
	"goskeleton/app/global/variable"
	"goskeleton/app/http/middleware/my_jwt"
	"goskeleton/app/model"
	"goskeleton/app/utils/response"
	"io/ioutil"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
)

type WeChat struct {
}

// 定义一个结构体来接收微信返回的数据
type WeChatResponse struct {
	OpenID     string `json:"openid"`
	SessionKey string `json:"session_key"`
	UnionID    string `json:"unionid"`
	ErrCode    int    `json:"errcode"`
	ErrMsg     string `json:"errmsg"`
}

// 定义 JWT 的 Claims 结构体

// 定义 JWT 的 Claims 结构体

func (w *WeChat) GetUserOpenId(ctx *gin.Context) {
	// 微信鉴权的url
	authUrl := "https://api.weixin.qq.com/sns/jscode2session?grant_type=authorization_code"
	authUrl += "&appid=" + "wxd74c252b85d6a0c9" + "&secret=" + "c977aea2bb6ec16366732bd9b481a4c8" + "&js_code=" + ctx.Query("code")

	// 发送请求
	resp, err := http.Get(authUrl)
	if err != nil {
		variable.ZapLog.Error("微信鉴权请求失败", zap.Error(err))
		return
	}
	defer resp.Body.Close()

	// 读取响应体
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		variable.ZapLog.Error("读取响应体失败", zap.Error(err))
		return
	}

	// 解析 JSON 数据
	var weChatResponse WeChatResponse
	err = json.Unmarshal(body, &weChatResponse)
	if err != nil {
		variable.ZapLog.Error("解析 JSON 数据失败", zap.Error(err))
		return
	}

	// 检查是否有错误码
	if weChatResponse.ErrCode != 0 {
		variable.ZapLog.Error("微信鉴权失败", zap.Int("errcode", weChatResponse.ErrCode), zap.String("errmsg", weChatResponse.ErrMsg))
		return
	}
	//获取到了openId,在数据库中查看是否有该用户
	// 创建 ProductModel 实例让数据库能进行连接
	userModel := model.CreateUserFactory1("")
	avatarUrl := ctx.Query(`avatarUrl`)
	nickName := ctx.Query(`nickName`)
	user, err := userModel.CheckUserRegister(weChatResponse.OpenID, avatarUrl, nickName)
	if err != nil {
		return
	}
	// 创建 JWT 实例
	jwtSign := my_jwt.CreateMyJWT(variable.ConfigYml.GetString("Jwt.Secret"))

	// 定义 token 的过期时间
	expirationTime := time.Now().Add(24 * time.Hour) // 24小时后过期

	// 创建 Claims
	claims := my_jwt.CustomClaims{
		OpenID: weChatResponse.OpenID,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: expirationTime.Unix(),
		},
	}
	// 生成 token
	token, err := jwtSign.CreateToken(claims)
	if err != nil {
		variable.ZapLog.Error("生成 token 失败", zap.Error(err))
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": "生成 token 失败"})
		return
	}
	//封装返回的user用户
	// 返回 token
	response.Success(ctx, "获取成功", gin.H{"token": token, "openid": weChatResponse.OpenID, "user": user})
}
